/*
 * @ : Copyright (c) 2021 Phytium Information Technology, Inc. 
 *  
 * SPDX-License-Identifier: Apache-2.0.
 * 
 * @Date: 2021-09-14 10:47:59
 * @LastEditTime: 2021-10-09 09:56:48
 * @Description:  This files is for sdmmc intrrupt ctrl implementation
 * 
 * @Modify History: 
 *  Ver   Who        Date         Changes
 * ----- ------     --------    --------------------------------------
 * 1.0   Zhugengyu   2021/8/6    init
 */
#include "ft_assert.h"
#include "parameters.h"
#include "interrupt.h"
#include "f_sdmmc_hw.h"
#include "f_sdmmc.h"

u32 FSdmmcGetIntrMask(FSdmmcCtrl *ctrl_p, u32 intr_type)
{
    FT_ASSERTZERONUM(ctrl_p);
    u32 mask;

    switch (intr_type)
    {
        case FSDMMC_CMD_INTR:
            mask = FSDMMC_GET_NORMAL_INT(ctrl_p);
            break;
        case FSDMMC_ERROR_INTR:
            mask = FSDMMC_GET_ERROR_INT(ctrl_p);
            break;
        case FSDMMC_DMA_BD_INTR:
            mask = FSDMMC_GET_BD_ISR(ctrl_p);
            break;
        default:
            FT_ASSERTZERONUM(0);
            break;
    }

    return mask;
}

void FSdmmcSetIntrMask(FSdmmcCtrl *ctrl_p, u32 intr_type, u32 mask, boolean enable)
{
    FT_ASSERTVOID(ctrl_p);
    u32 reg_val;

    reg_val = FSdmmcGetIntrMask(ctrl_p, intr_type);

    if (TRUE == enable)
        reg_val |= mask;
    else
        reg_val &= ~mask;

    switch (intr_type)
    {
        case FSDMMC_CMD_INTR:
            FSDMMC_SET_NORMAL_INT(ctrl_p, reg_val);
            break;
        case FSDMMC_ERROR_INTR:
            FSDMMC_SET_ERROR_INT(ctrl_p, reg_val);
            break;
        case FSDMMC_DMA_BD_INTR:
            FSDMMC_SET_BD_ISR(ctrl_p, reg_val);
            break;
        default:
            FT_ASSERTVOID(0);
            break;
    }

    return;
}

void FSdmmcDisableIntr(FSdmmcCtrl *ctrl_p)
{
    FT_ASSERTVOID(ctrl_p);
    FSDMMC_SET_NORMAL_INT(ctrl_p, 0x0);
    FSDMMC_SET_ERROR_INT(ctrl_p, 0x0);
    FSDMMC_SET_BD_ISR(ctrl_p, 0x0);

    FSDMMC_CLR_NORMAL_INT_STATUS(ctrl_p);
    FSDMMC_CLR_ERROR_INT_STATUS(ctrl_p);
    FSDMMC_CLR_BD_ISR_STATUS(ctrl_p);      
}

u32 FSdmmcInitIntr(FSdmmcCtrl *ctrl_p)
{
    FT_ASSERTZERONUM(ctrl_p);

    FSdmmcConfig *config_p = &ctrl_p->config;
    u32 loop;

    /* disable all sdci irq */
    FSdmmcDisableIntr(ctrl_p);

    /* umask sdci irq */
    for (loop = 0; loop < (u32)FSDMMC_INTR_NUM; loop++)
    {
        InterruptSetPriority(config_p->irq_num[loop], config_p->irq_priority[loop]);
        InterruptInstall(config_p->irq_num[loop], ctrl_p->intr_handler[loop], ctrl_p, config_p->irq_name[loop]);

        if (TRUE == config_p->enable_irq[loop])
            InterruptUmask(config_p->irq_num[loop]);
        else
            InterruptMask(config_p->irq_num[loop]);
    }

    return FSDMMC_SUCCESS;
}